package com.xzzz.common.wechat.manager;

import com.xzzz.common.base.exception.XzAbstractException;
import com.xzzz.common.base.exception.XzException500;
import com.xzzz.common.base.util.json.JsonUtil;
import com.xzzz.common.wechat.WxProperties;
import com.xzzz.common.wechat.pojo.WxBaseDTO;
import com.xzzz.common.wechat.pojo.WxCodeUnlimitedDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;

/**
 * @author xzzz
 * 
 */
@Slf4j
@Component
public class WxQRCodeManager extends AbstractWxManager {
    /** 小程序码地址 */
    private static final String WECHAT_CODE_UNLIMITED_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";
    /** 店铺小程序二维码类型 */
    private static final String SHOP     = "SHOP";
    /** 店铺小程序地址 */
    private static final String SHOP_URL = "";
    /** 商品小程序二维码类型 */
    private static final String ITEM     = "ITEM";
    /** 商品小程序地址 */
    private static final String ITEM_URL = "";
    /** 最大调用次数 */
    private static final int RETRY_MAX_NUM = 3;

    @Autowired
    private WxProperties properties;

    @Autowired
    private WxAuthManager wxAuthManager;

    public byte[] getUnlimitedCode (String scene,String type) {
        WxCodeUnlimitedDTO wxCodeUnlimitedDTO = new WxCodeUnlimitedDTO(scene);

        // 设置小程序码跳转地址
        if (SHOP.equals(type)) {
            wxCodeUnlimitedDTO.setPage(SHOP_URL);
        } else if (ITEM.equals(type)) {
            wxCodeUnlimitedDTO.setPage(ITEM_URL);
        } else {
            throw new XzException500("小程序码类型错误: " + type);
        }

        // 调用次数
        int retryNum = 1;
        // 是否重试
        boolean retry = true;

        while (true) {
            byte[] bytes = postBodyGetBytes(WECHAT_CODE_UNLIMITED_URL,wxCodeUnlimitedDTO,"");
            if (bytes.length == 0) {
                throw new XzException500("未获取到微信响应内容");
            } else {
                // 获取到返回体后尝试解析为响应体
                String res = new String(bytes, StandardCharsets.UTF_8);
                WxBaseDTO wxBaseDO;
                try {
                    wxBaseDO = JsonUtil.toObj(res,WxBaseDTO.class);
                    // 解析响应体成功,证明该接口返回图片流错误,返回的是错误JSON
                    if (wxBaseDO != null) {
                        retry = checkResult(wxBaseDO,retry);
                        if (retry && retryNum < RETRY_MAX_NUM) {
                            log.warn("[微信模块] 调用接口失效TOKEN无效,即将刷新TOKEN,并准备第 [{}] 次调用",retryNum);
                            retryNum++;
                            wxAuthManager.refreshAuthAccessToken(properties.getMp().getAppId());
                        } else {
                            retry = false;
                        }
                        continue;
                    }
                } catch (Exception e) {
                    // 捕获到自定义异常时,需要将异常抛出供advice处理
                    if (e instanceof XzAbstractException) {
                        log.error("[微信模块] 获取微信二维码错误");
                        throw e;
                    }
                    // 如果抛出转换异常,则说明响应体为流,无法转换为Json
                    log.info("[微信模块] 获取二维码成功");
                }
                return bytes;
            }
        }
    }

    @Override
    protected String getAuthAccessToken(String appId) {
        return wxAuthManager.getAuthAccessToken(appId);
    }
}
